<script setup lang="ts">
import { reactive, ref, watch } from 'vue';
import { PinInputInput, PinInputRoot } from 'radix-vue';
import { useBoolean } from '@sa/hooks';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import { useCaptcha } from '@/hooks/business/captcha';
import Title from '@/components/common/login/auth-title.vue';

defineOptions({
  name: 'CodeLogin'
});

interface Emit {
  (event: 'changeModule', module: UnionKey.LoginModule): void;
}
const emit = defineEmits<Emit>();

const { formRef, validate } = useNaiveForm();
const { bool: submitLoading, setBool: setSubmitLoading } = useBoolean();
const { label, isCounting, loading, getCaptcha } = useCaptcha();

interface FormModel {
  phone: string;
  code: string;
}

const model: FormModel = reactive({
  phone: '',
  code: ''
});

const { formRules } = useFormRules();
type RuleKey = keyof FormModel;

const codeRules = formRules.code.map(i => {
  return {
    ...i,
    key: 'code'
  };
});
const rules: Record<RuleKey, CommonType.WithArray<App.Global.FormRule>> = {
  phone: formRules.phone,
  code: codeRules
};

async function handleSubmit() {
  await validate();
  setSubmitLoading(true);
}

const inputValue = ref<string[]>([]);
const codeSize = 6;
function handleComplete(e: string[]) {
  model.code = e.join('');
}

watch(
  () => model.code,
  () => {
    inputValue.value = model.code?.split('') ?? [];
  }
);

watch(inputValue, val => {
  model.code = val.join('');
  formRef.value?.validate(
    () => {},
    rule => {
      return rule?.key === 'code';
    }
  );
});
</script>

<template>
  <div @keydown.enter.prevent="handleSubmit">
    <Title title="欢迎回来 📲">
      <template #desc>
        <span class="text-muted-foreground">请输入您的手机号码以开始管理您的项目</span>
      </template>
    </Title>

    <NForm ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
      <NFormItem path="phone">
        <NInput v-model:value="model.phone" placeholder="手机号码" />
      </NFormItem>
      <NFormItem path="code">
        <div class="w-full flex-y-center gap-16px">
          <PinInputRoot
            v-model="inputValue"
            otp
            placeholder="○"
            type="number"
            class="mt-1 flex items-center"
            @complete="handleComplete"
          >
            <PinInputInput
              v-for="(id, index) in codeSize"
              :key="id"
              :index="index"
              class="bg-background border-input relative h-10 w-8 flex items-center justify-center border-y border-r text-center text-sm transition-all focus:relative focus:z-10 md:w-10 first:border-l first:rounded-l-md last:rounded-r-md focus:outline-none focus:ring-2"
            />
          </PinInputRoot>
          <NButton
            size="large"
            :disabled="isCounting"
            :loading="loading"
            class="flex-1"
            @click="getCaptcha(model.phone)"
          >
            {{ label }}
          </NButton>
        </div>
      </NFormItem>
    </NForm>
    <NSpace :size="16" vertical>
      <NButton type="primary" block :loading="submitLoading" @click="handleSubmit">登录</NButton>
      <NButton block @click="emit('changeModule', 'pwd-login')">返回</NButton>
    </NSpace>
  </div>
</template>

<style scoped></style>
